package pyip.lib.javalearn.classloader.load.rule;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class MyClassLoader extends ClassLoader {

    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        System.out.println();
        System.out.println("------ MyClassLoader.loadClass");
        System.out.println("load, findLoadedClass - " + name + ": " + findLoadedClass(name));
        // System.out.println("load, findLoadedClass - classloader.load.A: " + findLoadedClass("pyip.lib.javalearn.classloader.load.rule.A"));
        System.out.println("load, findLoadedClass - java.lang.Object: " + findLoadedClass("java.lang.Object"));
        Class<?> c1 = null;
        if (name.startsWith("java") || name.startsWith("javax")) {
            c1 = super.loadClass(name);
        } else if (name.endsWith("pyip.lib.javalearn.classloader.load.rule.B")) {
            c1 = findLoadedClass(name);
            if (null == c1) {
                c1 = findClass(name);
                resolveClass(c1);
            }

            // if(null == c1) {
            // c1 = findClass(name);
            // resolveClass(c1);
            // } else {
            // c1 = super.loadClass(name);
            // }
        } else {
            // c1 = super.loadClass(name);

            c1 = findLoadedClass(name);
            if (null == c1) {
                c1 = findClass(name);
                resolveClass(c1);
            }
        }
        return c1;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        System.out.println();
        System.out.println("------ MyClassLoader.findClass");
        System.out.println("find, findLoadedClass - " + name + ": " + findLoadedClass(name));

        String path = name.replace(".", "/").concat(".class");
        InputStream in = null;
        ByteArrayOutputStream out = null;
        try {
            in = ClassLoader.getSystemResourceAsStream(path);
            out = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int size = 0;
            int totalSize = 0;
            while ((size = in.read(buffer)) != -1) {
                out.write(buffer, 0, size);
                totalSize += size;
            }

            return defineClass(name, out.toByteArray(), 0, totalSize);
        } catch (IOException e) {
            throw new ClassNotFoundException();
        } finally {
            if (null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}
